/**
 * 生产订单服务 - 连接用友云API
 * 基于MO.py的配置和字段映射
 */

const crypto = require('crypto');
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
require('dotenv').config();

// 智能代理配置
const PROXY_CONFIG = {
  enabled: process.env.USE_PROXY === 'true' || false, // 通过环境变量控制
  host: process.env.PROXY_HOST || '192.168.0.1',
  port: process.env.PROXY_PORT || 808,
  protocol: process.env.PROXY_PROTOCOL || 'http',
  autoDetect: true // 自动检测是否需要代理
};

// 创建代理agent
const proxyAgent = PROXY_CONFIG.enabled
  ? new HttpsProxyAgent(`${PROXY_CONFIG.protocol}://${PROXY_CONFIG.host}:${PROXY_CONFIG.port}`)
  : null;

// 智能请求函数 - 自动尝试直连和代理
async function smartRequest(url, options = {}) {
  const baseOptions = {
    timeout: 15000,
    ...options
  };

  // 首先尝试直连
  if (!PROXY_CONFIG.enabled || PROXY_CONFIG.autoDetect) {
    try {
      console.log(`🔗 尝试直连: ${url}`);
      const response = await axios.get(url, {
        ...baseOptions,
        proxy: false
      });
      console.log(`✅ 直连成功: ${url}`);
      return response;
    } catch (error) {
      console.log(`❌ 直连失败: ${error.message}`);

      // 如果不是超时错误，直接抛出
      if (!error.message.includes('timeout') && !error.message.includes('ECONNREFUSED')) {
        throw error;
      }
    }
  }

  // 尝试使用代理
  if (proxyAgent || PROXY_CONFIG.autoDetect) {
    try {
      console.log(`🔗 尝试代理连接: ${url}`);
      const response = await axios.get(url, {
        ...baseOptions,
        httpsAgent: proxyAgent,
        proxy: false
      });
      console.log(`✅ 代理连接成功: ${url}`);
      return response;
    } catch (error) {
      console.log(`❌ 代理连接失败: ${error.message}`);
      throw error;
    }
  }

  throw new Error('所有连接方式都失败了');
}

class ProductionOrderService {
  constructor() {
    // 从MO.py提取的配置信息
    this.config = {
      TENANT_ID: process.env.YONSUITE_TENANT_ID || 'a2wmiscz',
      APP_KEY: process.env.YONSUITE_APP_KEY || '500748557be74fe7aa78c566342a5e64',
      APP_SECRET: process.env.YONSUITE_APP_SECRET || '8970eb0d2ff418f62bdd3e926db33e13c556cfb2',
      ORG_ID: process.env.YONSUITE_ORG_ID || '2108054698226352134',
      PAGE_SIZE: parseInt(process.env.YONSUITE_PAGE_SIZE || '500')
    };
    
    this.accessToken = null;
    this.gatewayUrl = null;
    this.tokenExpiry = null;
  }

  /**
   * 判断是否为令牌失效错误
   */
  isTokenInvalidMessage(msg) {
    if (!msg) return false;
    const s = String(msg).toLowerCase();
    return s.includes('非法token') || s.includes('invalid token') || s.includes('token invalid') || s.includes('token is invalid');
  }

  /**
   * 生成API签名
   */
  generateSignature(appSecret, params) {
    const sortedParams = Object.keys(params)
      .sort()
      .map(key => `${key}${params[key]}`)
      .join('');
    
    const signature = crypto
      .createHmac('sha256', appSecret)
      .update(sortedParams)
      .digest('base64');
    
    return encodeURIComponent(signature);
  }

  /**
   * 获取数据中心域名
   */
  async getDataCenterDomains() {
    try {
      const url = `https://apigateway.yonyoucloud.com/open-auth/dataCenter/getGatewayAddress?tenantId=${this.config.TENANT_ID}`;
      const response = await smartRequest(url);
      
      if (response.data.code !== '00000') {
        throw new Error(`获取数据中心域名失败: ${response.data.message}`);
      }
      
      return response.data.data;
    } catch (error) {
      console.error('获取数据中心域名失败:', error.message);
      throw error;
    }
  }

  /**
   * 获取访问令牌
   */
  async getAccessToken() {
    try {
      // 如果token还有效，直接返回
      if (this.accessToken && this.tokenExpiry && Date.now() < this.tokenExpiry) {
        return this.accessToken;
      }

      // 获取数据中心信息
      const dataCenterInfo = await this.getDataCenterDomains();
      this.gatewayUrl = dataCenterInfo.gatewayUrl;
      const tokenUrl = dataCenterInfo.tokenUrl;

      // 生成签名参数
      const timestamp = Date.now().toString();
      const params = {
        appKey: this.config.APP_KEY,
        timestamp: timestamp
      };
      
      const signature = this.generateSignature(this.config.APP_SECRET, params);
      
      // 请求token
      const url = `${tokenUrl}/open-auth/selfAppAuth/getAccessToken?appKey=${this.config.APP_KEY}&timestamp=${timestamp}&signature=${signature}`;
      const response = await smartRequest(url);
      
      if (response.data.code !== '00000') {
        throw new Error(`获取Token失败: ${response.data.message}`);
      }
      
      this.accessToken = response.data.data.access_token;
      // 用友云Token有效期为2小时，提前10分钟刷新
      this.tokenExpiry = Date.now() + (110 * 60 * 1000); // 110分钟后过期
      
      const expiryTime = new Date(this.tokenExpiry);
      console.log('✅ 用友云API Token获取成功');
      console.log(`🕐 Token过期时间: ${expiryTime.toLocaleString()}`);
      return this.accessToken;
      
    } catch (error) {
      console.error('获取访问令牌失败:', error.message);
      throw error;
    }
  }

  /**
   * 获取Token状态信息
   */
  getTokenStatus() {
    if (!this.accessToken) {
      return {
        hasToken: false,
        message: '未获取Token'
      };
    }

    const now = Date.now();
    const timeLeft = this.tokenExpiry - now;
    const minutesLeft = Math.floor(timeLeft / (60 * 1000));

    return {
      hasToken: true,
      isValid: timeLeft > 0,
      expiryTime: new Date(this.tokenExpiry).toLocaleString(),
      minutesLeft: minutesLeft,
      message: timeLeft > 0 ?
        `Token有效，剩余${minutesLeft}分钟` :
        'Token已过期，需要刷新'
    };
  }

  /**
   * 获取生产订单列表
   */
  async getProductionOrders(options = {}) {
    try {
  await this.getAccessToken();

      const {
        startDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], // 默认30天前
        endDate = new Date().toISOString().split('T')[0], // 默认今天
        pageIndex = 1,
        pageSize = this.config.PAGE_SIZE,
        status = null, // 订单状态筛选
        code = null, // 订单号筛选
        requestTimeoutMs = 60000
      } = options;

      const payload = {
        pageIndex,
        pageSize,
        org: this.config.ORG_ID,
        vouchdate_begin: startDate,
        vouchdate_end: endDate,
        isShowProcess: 1,
        isShowMaterial: true,
        isShowByProduct: true,
        isShowActivity: true
      };

      // 如果指定了状态，添加状态筛选
      if (status !== null) {
        payload.status = status;
      }

      // 如果指定了订单号，添加订单号筛选
      if (code !== null) {
        payload.code = code;
      }

    const doRequest = async () => axios.post(
        `${this.gatewayUrl}/yonbip/mfg/productionorder/list?access_token=${this.accessToken}`,
        payload,
        { 
      timeout: requestTimeoutMs,
          headers: {
            'Content-Type': 'application/json'
          }
        }
      );

      let response = await doRequest();

      if (response.data.code !== '200') {
        // 若为token失效，清空并刷新一次后重试
        if (this.isTokenInvalidMessage(response.data.message)) {
          this.accessToken = null;
          this.tokenExpiry = null;
          await this.getAccessToken();
          response = await doRequest();
          if (response.data.code !== '200') {
            throw new Error(`获取生产订单失败: ${response.data.message}`);
          }
        } else {
          throw new Error(`获取生产订单失败: ${response.data.message}`);
        }
      }

      const data = response.data.data;
      return {
        success: true,
        data: {
          orders: data.recordList || [],
          total: data.totalCount || 0,
          pageIndex: data.pageIndex || pageIndex,
          pageSize: data.pageSize || pageSize
        }
      };

  } catch (error) {
      console.error('获取生产订单失败:', error.message);
      return {
        success: false,
        error: error.message,
        data: {
          orders: [],
          total: 0,
          pageIndex: 1,
          pageSize: 0
        }
      };
    }
  }

  /**
   * 获取订单详情（包含物料信息）
   */
  async getOrderDetail(orderId, options = {}) {
    try {
      await this.getAccessToken();
      const { timeoutMs = 30000 } = options;
      
      const doRequest = async () => axios.get(
        `${this.gatewayUrl}/yonbip/mfg/productionorder/detail/${orderId}?access_token=${this.accessToken}`,
        { timeout: timeoutMs }
      );

      let response = await doRequest();

      if (response.data.code !== '200') {
        if (this.isTokenInvalidMessage(response.data.message)) {
          this.accessToken = null;
          this.tokenExpiry = null;
          await this.getAccessToken();
          response = await doRequest();
          if (response.data.code !== '200') {
            throw new Error(`获取订单详情失败: ${response.data.message}`);
          }
        } else {
          throw new Error(`获取订单详情失败: ${response.data.message}`);
        }
      }

      return {
        success: true,
        data: response.data.data
      };

    } catch (error) {
      console.error('获取订单详情失败:', error.message);
      return {
        success: false,
        error: error.message,
        data: null
      };
    }
  }

  /**
   * 获取物料编码列表（用于PPH系统物料匹配）
   */
  async getMaterialCodes(orderIds = []) {
    try {
      const materials = new Set();
      
      for (const orderId of orderIds) {
        const orderDetail = await this.getOrderDetail(orderId);
        if (orderDetail.success && orderDetail.data) {
          // 提取产品物料编码
          if (orderDetail.data.OrderProduct) {
            orderDetail.data.OrderProduct.forEach(product => {
              if (product.productCode) {
                materials.add(product.productCode);
              }
            });
          }
          
          // 提取材料物料编码
          if (orderDetail.data.orderMaterial) {
            orderDetail.data.orderMaterial.forEach(material => {
              if (material.productCode) {
                materials.add(material.productCode);
              }
            });
          }
        }
      }

      return {
        success: true,
        data: Array.from(materials)
      };

    } catch (error) {
      console.error('获取物料编码失败:', error.message);
      return {
        success: false,
        error: error.message,
        data: []
      };
    }
  }

  /**
   * 测试API连接
   */
  async testConnection() {
    try {
      await this.getAccessToken();
      
      // 测试获取一条订单
      const result = await this.getProductionOrders({ pageSize: 1 });
      
      return {
        success: true,
        message: '用友云API连接成功',
        config: {
          tenantId: this.config.TENANT_ID,
          orgId: this.config.ORG_ID,
          gatewayUrl: this.gatewayUrl
        },
        tokenStatus: this.getTokenStatus(),
        testResult: result
      };

    } catch (error) {
      return {
        success: false,
        message: '用友云API连接失败',
        error: error.message
      };
    }
  }
}

module.exports = ProductionOrderService;
